<template>
  <el-row v-if="!initializing">
    <el-col
      v-for="(field, index) in showFieldList"
      :key="index"
      :span="field.colCnt || 11"
    >
      <el-form-item
        :label="field.aliasName || field.fieldName"
        :label-width="props.labelWidth"
        :align="align[props.labelAlign] || 'right'"
        :prop="field.fieldName"
      >
        <template #label>
          <span v-if="field.description" style="display: inline-flex">
            <span
              :style="{marginRight: '3px', color: field.labelColor ? field.labelColor : ''}"
            >{{field.aliasName || field.fieldName}}</span>
            <el-tooltip popper-class="padding-10-15" effect="light">
              <template #content>
                <div>{{field.description}}</div>
              </template>
              <span><cc-icon iconId="018dca8ec9890493be26" style="color: #333" /></span>
            </el-tooltip>
          </span>
          <span
            v-else
            :style="{color: field.labelColor ? field.labelColor : ''}"
          >{{field.aliasName || field.fieldName}}</span>
        </template>
        <component
          :is="getComponent(field)"
          v-bind="getOptions(field)"
          v-bind:prop="field.fieldName"
          v-bind:option="formData[field.fieldName + '_name']
            ? {id: formData[field.fieldName], name: formData[field.fieldName + '_name']} : {}"
        />
      </el-form-item>
    </el-col>
  </el-row>
</template>

<script setup>
import { ref, onMounted, inject, computed } from 'vue';
import tool from "@/utils/tool";
import { useDisabled } from 'element-plus';

const props = defineProps({
  fieldList: {
    type: Array,
    default: () => []
  },
  autofillList: Array,
  displayList: Array,
  labelWidth: {
    type: [String, Number],
    default: '120px'
  },
  labelAlign: {
    type: String,
    default: '居右'
  }
});

const disabled = useDisabled();
const formData = inject('formData');
const initializing = ref(true);
const fieldList = ref([]);
const align = ref({'居左': 'left', '居中': 'center', '居右': 'right'});
const component = ref({
  '单行文本框': 'cc-input',
  '密码文本框': 'cc-password',
  '多行文本框': 'cc-textarea',
  '富文本框': 'cc-rich-editor',
  '单选框': 'cc-radio',
  '多选框': 'cc-checkbox',
  '下拉框': 'cc-select',
  '多选下拉框': 'cc-selects',
  '开关': 'cc-switch',
  '字符': 'cc-input',
  '整数': 'cc-number',
  '小数': 'cc-number',
  '日期': 'cc-date',
  '时间': 'cc-datetime',
  '图片': 'cc-image',
  '视频': 'cc-video',
  '附件': 'cc-affix',
  '弹窗选择': 'cc-dialog-select',
  '下拉选择': 'cc-remote-select',
  '树形控件': 'cc-tree',
  '区划树': 'cc-region-tree',
  '单位树': 'cc-unit-tree',
  '企业树': 'cc-entp-tree',
  '部门树': 'cc-organization-tree',
  '人员树': 'cc-employee-tree',
  '字典树': 'cc-dict-tree',
  '字典开关': 'cc-dict-switch',
  '字典单选框': 'cc-dict-radio',
  '字典下拉框': 'cc-dict-select',
  '单位多选': 'cc-units-tree',
  '企业多选': 'cc-entps-tree',
  '部门多选': 'cc-organizations-tree',
  '人员多选': 'cc-employees-tree',
  '角色多选': 'cc-roles',
});
const getComponent = (field) => {
  if (field.fieldType === '字符') {
    if (field.enumerate === '1') {
      return component.value[field.enumerateType];
    } else {
      return component.value[field.inputType];
    }
  } else if ("整数、小数、日期、时间、图片、视频、附件".indexOf(field.fieldType) >= 0) {
    return component.value[field.fieldType];
  } else if (field.fieldType === '联动') {
    if (field.relevanceType === '数据模型') {
      if (field.dialogPageId) {
        return component.value['弹窗选择'];
      } else {
        let relevanceList = getDataField(field.id).relevanceList || [];
        if (relevanceList.length === 1 && !relevanceList[0].parentFieldId) {
          return component.value['下拉选择'];
        } else {
          return component.value['树形控件'];
        }
      }
    } else {
      return component.value[field.relevanceType];
    }
  } else if (field.fieldType === '大文本') {
    return component.value[field.inputType];
  }

  return 'cc-input';
};

const getOptions = (field) => {
  if (field.fieldType === '字符') {
    if (field.autoCreate === '1') {
      return {
        disabled: disabled.value || field.disabled || field.readonly,
        placeholder: field.readonly && !disabled.value ? field.description : '',
        rowLine: field.rowLine,
        valuePlaceholder: field.description || '系统自动生成'
      };
    } else if (field.enumerate === '1') {
      return {
        options: field.enumerateValue || '',
        disabled: disabled.value || field.disabled || field.readonly,
        rowLine: field.rowLine
      };
    } else {
      return {
        max: field.fieldSize || 100,
        disabled: disabled.value || field.disabled || field.readonly,
        rowLine: field.rowLine,
        prefixText: field.prefixText,
        suffixText: field.suffixText
      };
    }
  } else if ("整数、小数".indexOf(field.fieldType) >= 0) {
    return {
      point: "整数" === field.fieldType ? 0 : field.fieldPrecision || 0,
      max: field.maxValue, min: field.minValue,
      disabled: disabled.value || field.disabled || field.readonly,
      prefixText: field.prefixText,
      suffixText: field.suffixText
    };
  } else if ("日期".indexOf(field.fieldType) >= 0) {
    return {
      format: field.format || undefined,
      valueFormat: field.format || undefined,
      type: field.inputType === '日期多选框' ? 'dates' : undefined,
      disabled: disabled.value || field.disabled || field.readonly,
    };
  } else if (field.fieldType === '图片') {
    return {
      limit: 1,
      maxSize: field.imageMaxSize,
      handDraw: field.handDraw,
      disabled: disabled.value || field.disabled || field.readonly,
    };
  } else if (field.fieldType === '视频') {
    return {
      limit: 1,
      maxSize: field.imageMaxSize || undefined,
      disabled: disabled.value || field.disabled || field.readonly,
    };
  } else if (field.fieldType === '联动') {
    if (field.relevanceType === '数据模型') {
      let relevanceList = getDataField(field.id).relevanceList || [];
      if (field.dialogPageId && relevanceList.length > 0) {
        const relevance = relevanceList[relevanceList.length - 1];
        const json = field.dialogJson
          ? JSON.parse(field.dialogJson)
          : {pageId: field.dialogPageId, width: 800, paramList: []};

        const inputParam = {};
        json.paramList.forEach(param => {
          if (param.manually) {
            inputParam[param.pageParamId] = param.filterValue;
            inputParam[param.pageParamName] = param.filterValue;
          } else {
            inputParam[param.pageParamId] = formData.value[param.fieldName] || '--blank-value--';
          }
        });

        return {
          pageId: json.pageId,
          dialogFullscreen: json.fullscreen === '1',
          dialogWidth: json.width,
          dialogTitle: field.aliasName || field.fieldName,
          inputParam: inputParam,
          idProp: relevance.nodeFieldName,
          nameProp: relevance.showFieldName,
        };
      }

      if (relevanceList.length === 1 && !relevanceList[0].parentFieldId) {
        return {
          dataModelId: relevanceList[0].dataModelId,
          filterName: relevanceList[0].showFieldName,
          idProp: relevanceList[0].nodeFieldId || undefined,
          nameProp: relevanceList[0].showFieldId || undefined,
          sortField: relevanceList[0].ordinalFieldId || undefined,
          disabled: disabled.value || field.disabled || field.readonly,
          queryList: parseQuery(field, relevanceList)
        };
      } else {
        return {
          dataFieldId: field.fieldId,
          leafSelect: relevanceList.length > 1,
          typeSelect: relevanceList[relevanceList.length - 1].id,
          disabled: disabled.value || field.disabled || field.readonly
        };
      }
    } else if (field.relevanceType.includes('字典')) {
      return {
        dictCode: field.relevanceDict || '',
        disabled: disabled.value || field.disabled || field.readonly,
        rowLine: field.rowLine,
        queryList: parseQuery(field, [])
      };
    } else {
      return {
        disabled: disabled.value || field.disabled || field.readonly,
        rowLine: field.rowLine
      };
    }
  }

  return { disabled: disabled.value || field.disabled || field.readonly };
};

const parseQuery = (field, relevanceList) => {
  const queryList = [];
  const json = field.dialogJson ? JSON.parse(field.dialogJson) : {};
  if (json.filterList && json.filterList.length > 0) {
    json.filterList.forEach(param => {
      if (param.manually) {
        queryList.push({
          filterFieldId: param.filterFieldId,
          filterValue: param.filterValue
        });
      } else {
        const field = props.fieldList.find(item => item.fieldId === param.filterValueFieldId);
        if (field && field.dataField) {
          queryList.push({
            filterFieldId: param.filterFieldId,
            dataFieldName: field.dataField.fieldName
          });
        }
      }
    });
  } else if (field.relevanceType.startsWith("字典") && field.nativeFieldId) {
    queryList.push({
      filterFieldId: 'pid',
      dataFieldName: field.nativeFieldName
    });
  } else {
    if (relevanceList
        && relevanceList.length > 0
        && relevanceList[0].filterFieldId
        && relevanceList[0].filterValueFieldId) {
      const field = props.fieldList.find(item => item.fieldId === relevanceList[0].filterValueFieldId);
      if (field && field.dataField) {
        queryList.push({
          filterFieldId: relevanceList[0].filterFieldId,
          dataFieldName: field.dataField.fieldName
        });
      } else {
        queryList.push({
          filterFieldId: relevanceList[0].filterFieldId,
          filterValue: relevanceList[0].filterValueFieldId
        });
      }
    }
  }

  return queryList;
}

const getDataField = (id) => {
  return (props.fieldList.find(field => field.id === id) || {}).dataField || {};
}

const init = () => {
  initializing.value = true;
  let resultList = [];
  props.fieldList.forEach(item => {
    let dataField = tool.deepClone(item.dataField);
    let formField = tool.deepClone(item);
    formField.fieldName = dataField.fieldName;

    for (let key in dataField) {
      if (Array.isArray(dataField[key]) || typeof dataField[key] === 'object') {
        dataField[key] = null;
      }
    }
    for (let key in formField) {
      if (Array.isArray(formField[key]) || typeof formField[key] === 'object') {
        formField[key] = null;
      }
    }

    let result = Object.assign(
      {},
      dataField,
      formField,
      {prop: dataField.id, readonly: formField.readonly === '1'}
    );
    resultList.push(tool.deepClone(result));
  });

  fieldList.value = resultList;
  initializing.value = false;
};

const showFieldList = computed(() => {
  return fieldList.value.filter(field => field.hide !== '1' && checkDisplay(field));
});

const checkDisplay = (field) => {
  let displayList = (props.displayList || []).filter(display => display.fieldName === field.fieldName);
  if (!displayList || displayList.length === 0) return true;

  let show = null;
  let hide = null;
  displayList.forEach(display => {
    if (!display.ruleList || display.ruleList.length === 0) return;

    if (display.type === '显示') {
      show = false;
      hide = false;
      (tool.groupBy(display.ruleList, (item) => [item.groupIndex || 999]) || []).forEach(ruleList => {
        show = show || checkRuleList(ruleList);
      });
    } else if (display.type === '隐藏') {
      show = true;
      hide = false;
      (tool.groupBy(display.ruleList, (item) => [item.groupIndex || 999]) || []).forEach(ruleList => {
        hide = hide || checkRuleList(ruleList);
      });
    } else if (display.type === '禁用') {
      let disabled = false;
      (tool.groupBy(display.ruleList, (item) => [item.groupIndex || 999]) || []).forEach(ruleList => {
        disabled = disabled || checkRuleList(ruleList);
      });
      field.disabled = disabled;
    }
  });
  return hide ? !hide : show == null ? true : show;
};

const checkRuleList = (ruleList) => {
  if (!ruleList || ruleList.length === 0) return false;

  let result = true;
  ruleList.forEach(rule => {
    let testValue = formData.value[rule.fieldName];
    switch(rule.type) {
      case "包含": {
        const field = props.fieldList.find(field => field.fieldName === rule.fieldName);
        if (field
            && field.dataField
            && field.dataField.fieldType === '字符'
            && field.dataField.enumerate === '1'
            && field.dataField.enumerateType.indexOf('多选') >= 0) {
          result = result && (testValue || '').split(',').includes(rule.value || '');
        } else {
          result = result && (testValue || '').indexOf(rule.value || '') >= 0;
        }
        break;
      }
      case "不包含":
        result = result && (testValue || '').indexOf(rule.value || '') === -1;
        break;
      case "等于":
        result = result && (testValue || '') === (rule.value || '');
        break;
      case "不等于":
        result = result && (testValue || '') !== (rule.value || '');
        break;
      case "大于":
        result = result && parseFloat(testValue || '0') > parseFloat(rule.value || '0');
        break;
      case "大于等于":
        result = result && parseFloat(testValue || '0') >= parseFloat(rule.value || '0');
        break;
      case "小于":
        result = result && parseFloat(testValue || '0') < parseFloat(rule.value || '0');
        break;
      case "小于等于":
        result = result && parseFloat(testValue || '0') <= parseFloat(rule.value || '0');
        break;
      default:
        result = false;
    }
  });
  return result;
};

onMounted(() => {
  init();
});
</script>

<style scoped>
</style>